{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 114,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import re\n",
    "import json\n",
    "\n",
    "from dotenv import load_dotenv\n",
    "from datasets import load_dataset\n",
    "from langchain_openai import ChatOpenAI\n",
    "import pandas as pd\n",
    "from tqdm import tqdm\n",
    "\n",
    "import promptquality as pq\n",
    "from tqdm import tqdm\n",
    "tqdm.pandas()\n",
    "\n",
    "load_dotenv(\"../.env\")\n",
    "# pq.login(\"console.demo.rungalileo.io\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [],
   "source": [
    "import unicodedata\n",
    "\n",
    "def normalize_string(text):\n",
    "    # Normalize unicode characters and remove diacritics\n",
    "    normalized = unicodedata.normalize('NFKD', text)\n",
    "    # Remove non-ASCII characters\n",
    "    ascii_text = normalized.encode('ASCII', 'ignore').decode('ASCII')\n",
    "    return ascii_text\n",
    "\n",
    "\n",
    "def extract_functions_list(text):\n",
    "    # Regex pattern to match the JSON array\n",
    "    pattern = r\"\\[\\s*{[\\s\\S]*?\\}\\s*\\]\"\n",
    "\n",
    "    # Find the match\n",
    "    match = re.search(pattern, text)\n",
    "    if match:\n",
    "        # Extract and parse the JSON string\n",
    "        json_str = match.group(0)\n",
    "        return json.loads(json_str)\n",
    "    return None\n",
    "\n",
    "\n",
    "def convert_tools_to_langchain_format(tools):\n",
    "    \"\"\"Convert tools from the given format to OpenAI function format\"\"\"\n",
    "\n",
    "    def convert_tool(tool):\n",
    "        # Start with the base function structure\n",
    "        converted = {\n",
    "            \"type\": \"function\",\n",
    "            \"function\": {\n",
    "                \"name\": re.sub(r\"[^\\w]\", \"_\", tool[\"name\"]),\n",
    "                \"description\": tool[\"description\"],\n",
    "                \"parameters\": {\"type\": \"object\", \"properties\": {}},\n",
    "            },\n",
    "        }\n",
    "\n",
    "        # Mapping of invalid types to valid JSON Schema types\n",
    "        type_mapping = {\n",
    "            \"float\": \"number\",\n",
    "            \"int\": \"integer\",\n",
    "            \"str\": \"string\",\n",
    "            \"bool\": \"boolean\",\n",
    "            \"dict\": \"object\",\n",
    "            \"list\": \"array\",\n",
    "            \"array\": \"array\",\n",
    "            \"decimal\": \"number\",\n",
    "            \"tuple\": \"array\",\n",
    "            \"number\": \"number\",\n",
    "            \"integer\": \"integer\",\n",
    "            \"string\": \"string\",\n",
    "            \"boolean\": \"boolean\",\n",
    "            \"object\": \"object\",\n",
    "        }\n",
    "\n",
    "        # Convert properties\n",
    "        if \"parameters\" in tool and \"properties\" in tool[\"parameters\"]:\n",
    "            for prop_name, prop_data in tool[\"parameters\"][\"properties\"].items():\n",
    "                converted_prop = {\n",
    "                    \"type\": type_mapping.get(prop_data[\"type\"], prop_data[\"type\"]),\n",
    "                    \"description\": prop_data[\"description\"],\n",
    "                }\n",
    "\n",
    "                # Handle enum if present\n",
    "                if \"enum\" in prop_data:\n",
    "                    converted_prop[\"enum\"] = prop_data[\"enum\"]\n",
    "\n",
    "                # Handle default if present\n",
    "                if \"default\" in prop_data:\n",
    "                    converted_prop[\"default\"] = prop_data[\"default\"]\n",
    "\n",
    "                converted[\"function\"][\"parameters\"][\"properties\"][\n",
    "                    prop_name\n",
    "                ] = converted_prop\n",
    "\n",
    "        # Handle required fields\n",
    "        if \"parameters\" in tool and \"required\" in tool[\"parameters\"]:\n",
    "            converted[\"function\"][\"parameters\"][\"required\"] = tool[\"parameters\"][\n",
    "                \"required\"\n",
    "            ]\n",
    "\n",
    "        return converted\n",
    "\n",
    "    # Handle both single tool and list of tools\n",
    "    if isinstance(tools, list):\n",
    "        return [convert_tool(tool) for tool in tools]\n",
    "    else:\n",
    "        return convert_tool(tools)\n",
    "\n",
    "def convert_tools_to_langchain_format_v2(tools):\n",
    "    \"\"\"Convert tools from the given format to OpenAI function format\"\"\"\n",
    "    \n",
    "    def convert_type(t):\n",
    "        type_mapping = {\n",
    "            \"float\": \"number\",\n",
    "            \"int\": \"integer\",\n",
    "            \"str\": \"string\",\n",
    "            \"bool\": \"boolean\",\n",
    "            \"dict\": \"object\",\n",
    "            \"list\": \"array\",\n",
    "            \"array\": \"array\",\n",
    "            \"decimal\": \"number\",\n",
    "            \"tuple\": \"array\",\n",
    "            \"number\": \"number\",\n",
    "            \"integer\": \"integer\",\n",
    "            \"string\": \"string\",\n",
    "            \"boolean\": \"boolean\",\n",
    "            \"object\": \"object\"\n",
    "        }\n",
    "        return type_mapping.get(t.lower() if isinstance(t, str) else t, \"string\")\n",
    "\n",
    "    def convert_property(prop_data):\n",
    "        converted_prop = {\n",
    "            \"type\": convert_type(prop_data[\"type\"]),\n",
    "            \"description\": prop_data[\"description\"]\n",
    "        }\n",
    "        \n",
    "        # Handle array types\n",
    "        if converted_prop[\"type\"] == \"array\":\n",
    "            if \"items\" in prop_data:\n",
    "                if isinstance(prop_data[\"items\"], dict):\n",
    "                    if \"type\" in prop_data[\"items\"]:\n",
    "                        converted_prop[\"items\"] = {\"type\": convert_type(prop_data[\"items\"][\"type\"])}\n",
    "                    elif \"properties\" in prop_data[\"items\"]:\n",
    "                        converted_prop[\"items\"] = {\n",
    "                            \"type\": \"object\",\n",
    "                            \"properties\": {\n",
    "                                k: convert_property(v) \n",
    "                                for k, v in prop_data[\"items\"][\"properties\"].items()\n",
    "                            }\n",
    "                        }\n",
    "                        if \"required\" in prop_data[\"items\"]:\n",
    "                            converted_prop[\"items\"][\"required\"] = prop_data[\"items\"][\"required\"]\n",
    "            else:\n",
    "                converted_prop[\"items\"] = {\"type\": \"string\"}  # Default type for array items\n",
    "        \n",
    "        # Handle enum and default\n",
    "        if \"enum\" in prop_data:\n",
    "            converted_prop[\"enum\"] = prop_data[\"enum\"]\n",
    "        if \"default\" in prop_data:\n",
    "            converted_prop[\"default\"] = prop_data[\"default\"]\n",
    "            \n",
    "        return converted_prop\n",
    "\n",
    "    def convert_tool(tool):\n",
    "        converted = {\n",
    "            \"type\": \"function\",\n",
    "            \"function\": {\n",
    "                \"name\": normalize_string(re.sub(r\"[^\\w]\", \"_\", tool[\"name\"])),\n",
    "                \"description\": tool[\"description\"],\n",
    "                \"parameters\": {\n",
    "                    \"type\": \"object\",\n",
    "                    \"properties\": {}\n",
    "                }\n",
    "            }\n",
    "        }\n",
    "        \n",
    "        if \"parameters\" in tool and \"properties\" in tool[\"parameters\"]:\n",
    "            converted[\"function\"][\"parameters\"][\"properties\"] = {\n",
    "                prop_name: convert_property(prop_data)\n",
    "                for prop_name, prop_data in tool[\"parameters\"][\"properties\"].items()\n",
    "            }\n",
    "            \n",
    "            if \"required\" in tool[\"parameters\"]:\n",
    "                converted[\"function\"][\"parameters\"][\"required\"] = tool[\"parameters\"][\"required\"]\n",
    "                \n",
    "        return converted\n",
    "\n",
    "    return [convert_tool(tool) for tool in tools] if isinstance(tools, list) else convert_tool(tools)\n",
    "\n",
    "def convert_messages_to_langchain_format(messages):\n",
    "    \"\"\"\n",
    "    Convert message format to match OpenAI's expected structure\n",
    "    with proper tool_calls handling\n",
    "    \"\"\"\n",
    "\n",
    "    def parse_arguments(args_str):\n",
    "        \"\"\"Convert argument string to proper JSON format\"\"\"\n",
    "        # Split by comma and process each key-value pair\n",
    "        pairs = [pair.strip() for pair in args_str.split(\",\")]\n",
    "        json_pairs = []\n",
    "\n",
    "        for pair in pairs:\n",
    "            if \"=\" in pair:\n",
    "                key, value = pair.split(\"=\")\n",
    "                # Clean up the key and value\n",
    "                key = key.strip()\n",
    "                value = value.strip('\"')\n",
    "                # Create proper JSON key-value pair\n",
    "                json_pairs.append(f'\"{key}\": \"{value}\"')\n",
    "\n",
    "        # Combine into valid JSON object\n",
    "        return \"{\" + \", \".join(json_pairs) + \"}\"\n",
    "\n",
    "    converted_messages = []\n",
    "\n",
    "    for i, message in enumerate(messages):\n",
    "        if message[\"from\"] == \"tool\":\n",
    "            # Get the previous assistant message\n",
    "            prev_message = messages[i - 1]\n",
    "\n",
    "            # Convert the string format tool call to proper structure\n",
    "            if prev_message[\"from\"] == \"assistant\" and \"[\" in prev_message[\"value\"]:\n",
    "                # Extract tool call information\n",
    "                content = prev_message[\"value\"].strip(\"[]\")\n",
    "                tool_name = normalize_string(re.sub(r\"[^\\w]\", \"_\", content.split(\"(\")[0]))\n",
    "                args_str = content.split(\"(\")[1].strip(\")\")\n",
    "\n",
    "                # Create properly formatted JSON arguments\n",
    "                json_args = parse_arguments(args_str)\n",
    "\n",
    "                # Add assistant message with tool_calls\n",
    "                assistant_message = {\n",
    "                    \"role\": \"assistant\",\n",
    "                    \"content\": None,\n",
    "                    \"tool_calls\": [\n",
    "                        {\n",
    "                            \"id\": f\"call_{i}\",\n",
    "                            \"type\": \"function\",\n",
    "                            \"function\": {\n",
    "                                \"name\": tool_name,\n",
    "                                \"arguments\": json_args,\n",
    "                            },\n",
    "                        }\n",
    "                    ],\n",
    "                }\n",
    "                converted_messages.append(assistant_message)\n",
    "\n",
    "                # Add tool response with proper format\n",
    "                tool_message = {\n",
    "                    \"role\": \"tool\",\n",
    "                    \"tool_call_id\": f\"call_{i}\",\n",
    "                    \"content\": message[\"value\"],\n",
    "                }\n",
    "                converted_messages.append(tool_message)\n",
    "\n",
    "        else:\n",
    "            # Keep non-tool messages as is\n",
    "            converted_messages.append(\n",
    "                {\"role\": message[\"from\"], \"content\": message[\"value\"]}\n",
    "            )\n",
    "\n",
    "    return converted_messages\n",
    "\n",
    "def keep_messages_till_last_user(messages):\n",
    "    \"\"\"\n",
    "    Keeps all messages in the conversation up until the last message with role 'user'.\n",
    "    \n",
    "    Args:\n",
    "        messages (list): List of dictionaries containing conversation messages.\n",
    "                        Each message should have at least a 'role' key.\n",
    "    \n",
    "    Returns:\n",
    "        list: Filtered list of messages up to and including the last user message.\n",
    "    \"\"\"\n",
    "    # Find the index of the last user message\n",
    "    last_user_index = -1\n",
    "    for i, message in enumerate(messages):\n",
    "        if message.get('role') == 'user':\n",
    "            last_user_index = i\n",
    "    \n",
    "    # If no user messages found, return empty list\n",
    "    if last_user_index == -1:\n",
    "        return []\n",
    "    \n",
    "    # Return all messages up to and including the last user message\n",
    "    return messages[:last_user_index + 1], last_user_index\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>system</th>\n",
       "      <th>conversations</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>You are an expert in composing functions. You ...</td>\n",
       "      <td>[{'from': 'user', 'value': 'I'm considering in...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>You are an expert in composing functions. You ...</td>\n",
       "      <td>[{'from': 'user', 'value': 'Could you please f...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>You are an expert in composing functions. You ...</td>\n",
       "      <td>[{'from': 'user', 'value': 'Hey, can you show ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>You are an expert in composing functions. You ...</td>\n",
       "      <td>[{'from': 'user', 'value': 'Could you provide ...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>You are an expert in composing functions. You ...</td>\n",
       "      <td>[{'from': 'user', 'value': 'Can you generate a...</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                              system  \\\n",
       "0  You are an expert in composing functions. You ...   \n",
       "1  You are an expert in composing functions. You ...   \n",
       "2  You are an expert in composing functions. You ...   \n",
       "3  You are an expert in composing functions. You ...   \n",
       "4  You are an expert in composing functions. You ...   \n",
       "\n",
       "                                       conversations  \n",
       "0  [{'from': 'user', 'value': 'I'm considering in...  \n",
       "1  [{'from': 'user', 'value': 'Could you please f...  \n",
       "2  [{'from': 'user', 'value': 'Hey, can you show ...  \n",
       "3  [{'from': 'user', 'value': 'Could you provide ...  \n",
       "4  [{'from': 'user', 'value': 'Can you generate a...  "
      ]
     },
     "execution_count": 116,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df = load_dataset(\"Team-ACE/ToolACE\", split=\"train\").to_pandas()\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "11300it [00:00, 25356.22it/s]"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "9606\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>tools_langchain</th>\n",
       "      <th>all_msgs</th>\n",
       "      <th>conversation</th>\n",
       "      <th>n_function_calls</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>[{'type': 'function', 'function': {'name': 'ne...</td>\n",
       "      <td>[{'role': 'user', 'content': 'I'm considering ...</td>\n",
       "      <td>[{'role': 'user', 'content': 'I'm considering ...</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>[{'type': 'function', 'function': {'name': 'Qu...</td>\n",
       "      <td>[{'role': 'user', 'content': 'Could you please...</td>\n",
       "      <td>[{'role': 'user', 'content': 'Could you please...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>[{'type': 'function', 'function': {'name': 'Ge...</td>\n",
       "      <td>[{'role': 'user', 'content': 'Hey, can you sho...</td>\n",
       "      <td>[{'role': 'user', 'content': 'Hey, can you sho...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>[{'type': 'function', 'function': {'name': 'Ge...</td>\n",
       "      <td>[{'role': 'user', 'content': 'Could you provid...</td>\n",
       "      <td>[{'role': 'user', 'content': 'Could you provid...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>[{'type': 'function', 'function': {'name': 'Ge...</td>\n",
       "      <td>[{'role': 'user', 'content': 'Can you generate...</td>\n",
       "      <td>[{'role': 'user', 'content': 'Can you generate...</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                     tools_langchain  \\\n",
       "0  [{'type': 'function', 'function': {'name': 'ne...   \n",
       "1  [{'type': 'function', 'function': {'name': 'Qu...   \n",
       "2  [{'type': 'function', 'function': {'name': 'Ge...   \n",
       "3  [{'type': 'function', 'function': {'name': 'Ge...   \n",
       "4  [{'type': 'function', 'function': {'name': 'Ge...   \n",
       "\n",
       "                                            all_msgs  \\\n",
       "0  [{'role': 'user', 'content': 'I'm considering ...   \n",
       "1  [{'role': 'user', 'content': 'Could you please...   \n",
       "2  [{'role': 'user', 'content': 'Hey, can you sho...   \n",
       "3  [{'role': 'user', 'content': 'Could you provid...   \n",
       "4  [{'role': 'user', 'content': 'Can you generate...   \n",
       "\n",
       "                                        conversation  n_function_calls  \n",
       "0  [{'role': 'user', 'content': 'I'm considering ...                 2  \n",
       "1  [{'role': 'user', 'content': 'Could you please...                 1  \n",
       "2  [{'role': 'user', 'content': 'Hey, can you sho...                 1  \n",
       "3  [{'role': 'user', 'content': 'Could you provid...                 1  \n",
       "4  [{'role': 'user', 'content': 'Can you generate...                 1  "
      ]
     },
     "execution_count": 117,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = []\n",
    "\n",
    "for row in tqdm(df.itertuples()):\n",
    "    try:\n",
    "        tools = convert_tools_to_langchain_format_v2(extract_functions_list(row.system))\n",
    "        all_msgs = convert_messages_to_langchain_format(row.conversations)\n",
    "        conversation, last_user_index = keep_messages_till_last_user(all_msgs)\n",
    "        n_function_call = len(all_msgs[last_user_index+1][\"content\"].split(\"(\")) - 1\n",
    "        data.append([tools, all_msgs, conversation, n_function_call])\n",
    "    except Exception as e:\n",
    "        pass\n",
    "\n",
    "df = pd.DataFrame(data, columns=[\"tools_langchain\", \"all_msgs\", \"conversation\", \"n_function_calls\"])\n",
    "print(len(df))\n",
    "\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "n_function_calls\n",
       "1     4664\n",
       "2     1521\n",
       "0     1109\n",
       "3     1109\n",
       "4      869\n",
       "5      205\n",
       "6       81\n",
       "7       27\n",
       "8       12\n",
       "9        3\n",
       "12       3\n",
       "18       1\n",
       "10       1\n",
       "14       1\n",
       "Name: count, dtype: int64"
      ]
     },
     "execution_count": 118,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.n_function_calls.value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>tools_langchain</th>\n",
       "      <th>all_msgs</th>\n",
       "      <th>conversation</th>\n",
       "      <th>n_function_calls</th>\n",
       "      <th>n_turns</th>\n",
       "      <th>len_query</th>\n",
       "      <th>n_tools</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>[{'type': 'function', 'function': {'name': 'ne...</td>\n",
       "      <td>[{'role': 'user', 'content': 'I'm considering ...</td>\n",
       "      <td>[{'role': 'user', 'content': 'I'm considering ...</td>\n",
       "      <td>2</td>\n",
       "      <td>4</td>\n",
       "      <td>146</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>[{'type': 'function', 'function': {'name': 'Qu...</td>\n",
       "      <td>[{'role': 'user', 'content': 'Could you please...</td>\n",
       "      <td>[{'role': 'user', 'content': 'Could you please...</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>121</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>[{'type': 'function', 'function': {'name': 'Ge...</td>\n",
       "      <td>[{'role': 'user', 'content': 'Hey, can you sho...</td>\n",
       "      <td>[{'role': 'user', 'content': 'Hey, can you sho...</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>153</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>[{'type': 'function', 'function': {'name': 'Ge...</td>\n",
       "      <td>[{'role': 'user', 'content': 'Could you provid...</td>\n",
       "      <td>[{'role': 'user', 'content': 'Could you provid...</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>187</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>[{'type': 'function', 'function': {'name': 'Ge...</td>\n",
       "      <td>[{'role': 'user', 'content': 'Can you generate...</td>\n",
       "      <td>[{'role': 'user', 'content': 'Can you generate...</td>\n",
       "      <td>1</td>\n",
       "      <td>3</td>\n",
       "      <td>215</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                     tools_langchain  \\\n",
       "0  [{'type': 'function', 'function': {'name': 'ne...   \n",
       "1  [{'type': 'function', 'function': {'name': 'Qu...   \n",
       "2  [{'type': 'function', 'function': {'name': 'Ge...   \n",
       "3  [{'type': 'function', 'function': {'name': 'Ge...   \n",
       "4  [{'type': 'function', 'function': {'name': 'Ge...   \n",
       "\n",
       "                                            all_msgs  \\\n",
       "0  [{'role': 'user', 'content': 'I'm considering ...   \n",
       "1  [{'role': 'user', 'content': 'Could you please...   \n",
       "2  [{'role': 'user', 'content': 'Hey, can you sho...   \n",
       "3  [{'role': 'user', 'content': 'Could you provid...   \n",
       "4  [{'role': 'user', 'content': 'Can you generate...   \n",
       "\n",
       "                                        conversation  n_function_calls  \\\n",
       "0  [{'role': 'user', 'content': 'I'm considering ...                 2   \n",
       "1  [{'role': 'user', 'content': 'Could you please...                 1   \n",
       "2  [{'role': 'user', 'content': 'Hey, can you sho...                 1   \n",
       "3  [{'role': 'user', 'content': 'Could you provid...                 1   \n",
       "4  [{'role': 'user', 'content': 'Can you generate...                 1   \n",
       "\n",
       "   n_turns  len_query  n_tools  \n",
       "0        4        146        6  \n",
       "1        3        121        6  \n",
       "2        3        153        4  \n",
       "3        3        187        6  \n",
       "4        3        215        5  "
      ]
     },
     "execution_count": 119,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df[\"n_turns\"] = df.conversation.apply(lambda x: len([m for m in x if m[\"role\"] == \"user\"]))\n",
    "df[\"len_query\"] = df.conversation.apply(lambda x: len(x[-1][\"content\"]))\n",
    "df[\"n_tools\"] = df.tools_langchain.apply(lambda x: len(x))\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "9606"
      ]
     },
     "execution_count": 120,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {},
   "outputs": [],
   "source": [
    "def helper_func(test_dict):\n",
    "    is_empty = True\n",
    "    if isinstance(test_dict, dict):\n",
    "        for _, sub in test_dict.items():\n",
    "            if not helper_func(sub):\n",
    "                is_empty = False\n",
    "                break\n",
    "    elif isinstance(test_dict, list):\n",
    "        for sub in test_dict:\n",
    "            if not helper_func(sub):\n",
    "                is_empty = False\n",
    "                break\n",
    "    else:\n",
    "        is_empty = False\n",
    "    return is_empty"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "602\n",
      "284\n"
     ]
    }
   ],
   "source": [
    "temp = df[(df.len_query > 100) & (df.n_function_calls == 0)]\n",
    "print(len(temp))\n",
    "temp = temp[~temp.conversation.apply(lambda x: \"1\" in str(x))]\n",
    "print(len(temp))\n",
    "temp = temp.sample(100, random_state=42)\n",
    "temp.iloc[70:90].to_parquet(\"../data/datasets/toolace_single_func_call_1.parquet\", engine=\"fastparquet\")\n",
    "temp.iloc[90:100].to_parquet(\"../data/datasets/toolace_single_func_call_2.parquet\", engine=\"fastparquet\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "langgraph",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
